package org.mappland.compltres.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.mappland.compltres.domain.Machine;
import org.mappland.compltres.domain.Order;
import org.mappland.compltres.domain.Type;
import org.mappland.compltres.dto.AdminReturnMachineDTO;
import org.mappland.compltres.dto.DateSectionDTO;
import org.mappland.compltres.dto.ReturnMachineDTO;
import org.mappland.compltres.mapper.MachineMapper;
import org.mappland.compltres.mapper.OrderMapper;
import org.mappland.compltres.mapper.TypeMapper;
import org.mappland.compltres.service.MachineService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class MachineServiceImpl extends ServiceImpl<MachineMapper, Machine> implements MachineService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private TypeMapper typeMapper;


    @Override
    public Boolean bookMachine(Integer machineId) {
        return this.getBaseMapper().bookMachine(machineId);
    }

    @Override
    public Boolean freeMachine(Integer machineId) {
        return this.getBaseMapper().freeMachine(machineId);
    }

    // 列出机型
    @Override
    public List<ReturnMachineDTO> listMachines(DateSectionDTO dateSectionDTO) {
        QueryWrapper<Machine> queryWrapper = new QueryWrapper<>();

        //查询空闲机型
        List<Machine> machineList = this.baseMapper.selectList(queryWrapper.eq("state", 0));
        Map<Integer, Machine> machineMap = machineList.stream().collect(Collectors.toMap(Machine::getId, m -> m, (k1, k2) -> k1));
        /**
         * lt：less than 小于
         * gt：greater than 大于
         */
        List<Order> orders = orderMapper.selectList(
                new QueryWrapper<Order>()
                        .eq("flag", 1)
                        .lt("in_time", dateSectionDTO.getInTime())
                        .lt("in_time", dateSectionDTO.getLeaveTime())
                        .gt("leave_time", dateSectionDTO.getInTime())
                        .lt("leave_time", dateSectionDTO.getLeaveTime())
                        .or()
                        .eq("flag", 1)
                        .gt("in_time", dateSectionDTO.getInTime())
                        .lt("in_time", dateSectionDTO.getLeaveTime())
                        .gt("leave_time", dateSectionDTO.getInTime())
                        .gt("leave_time", dateSectionDTO.getLeaveTime())
                        .or()
                        .eq("flag", 1)
                        .gt("in_time", dateSectionDTO.getInTime())
                        .lt("in_time", dateSectionDTO.getLeaveTime())
                        .gt("leave_time", dateSectionDTO.getInTime())
                        .lt("leave_time", dateSectionDTO.getLeaveTime())
                        .or()
                        .eq("flag", 1)
                        .lt("in_time", dateSectionDTO.getInTime())
                        .lt("in_time", dateSectionDTO.getLeaveTime())
                        .gt("leave_time", dateSectionDTO.getInTime())
                        .gt("leave_time", dateSectionDTO.getLeaveTime()
                )
        );
        for (Order order : orders) {
            machineMap.remove(order.getMachineId());
        }
        List<Machine> machines = new ArrayList<>(machineMap.values());

        List<ReturnMachineDTO> returnMachines = new ArrayList<>();

        if (machines.size() > 0) {
            for (Machine machine : machines) {
                System.out.println(machine);
                System.out.println(split(machine));
                ReturnMachineDTO returnMachineDTO = split(machine);

                BeanUtils.copyProperties(machine, returnMachineDTO);
                Type type = typeMapper.selectById(machine.getType());
                returnMachineDTO.setType(type);
                returnMachines.add(returnMachineDTO);
            }
        }
        return returnMachines;
    }

    @Override
    public ReturnMachineDTO machineDetail(Integer machineId) {
        Machine machine = this.getBaseMapper().selectById(machineId);
        ReturnMachineDTO returnMachineDTO = new ReturnMachineDTO();

        Type type = typeMapper.selectById(machine.getType());
        returnMachineDTO.setId(machine.getId());
        returnMachineDTO.setIp(machine.getIp());
        returnMachineDTO.setType(type);
        return returnMachineDTO;
    }

    @Override
    public AdminReturnMachineDTO adminReturnMachine(Integer machineId) {
        Machine machine = this.getBaseMapper().selectById(machineId);

        AdminReturnMachineDTO adminReturnMachineDTO = new AdminReturnMachineDTO();
        adminReturnMachineDTO.setMachine(machine);
        Type type = typeMapper.selectById(machine.getType());
        adminReturnMachineDTO.setType(type);

        return adminReturnMachineDTO;
    }

    private ReturnMachineDTO split(Machine machine) {
        ReturnMachineDTO returnMachineDTO = new ReturnMachineDTO();
        BeanUtils.copyProperties(machine, returnMachineDTO);

        returnMachineDTO.setIntroduces(machine.getIntroduce());
        return returnMachineDTO;
    }
}
